package com.deer.wms.instock.web;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deer.wms.ASN.manage.model.asn.AsnDetail;
import com.deer.wms.ASN.manage.model.asn.AsnMaster;
import com.deer.wms.ASN.manage.model.asn.AsnMasterCriteria;
import com.deer.wms.ASN.manage.service.AsnDetailService;
import com.deer.wms.ASN.manage.service.AsnMasterService;
import com.deer.wms.base.system.model.Area.AreaInfo;
import com.deer.wms.base.system.model.Item.ItemInfo;
import com.deer.wms.base.system.model.Pack.PackDetail;
import com.deer.wms.base.system.service.AreaInfoService;
import com.deer.wms.base.system.service.CellInfoService;
import com.deer.wms.base.system.service.ItemInfoService;
import com.deer.wms.base.system.service.PackDetailService;
import com.deer.wms.instock.service.impl.WaveServiceImpl;
import com.deer.wms.intercept.annotation.User;
import com.deer.wms.intercept.common.data.CurrentUser;
import com.deer.wms.inventory.model.Inventory.*;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.core.result.Result;
import com.deer.wms.project.root.core.result.ResultGenerator;
import com.deer.wms.project.root.util.StringUtils;
import com.deer.wms.system.manage.service.UserInfoService;
import com.deer.wms.ware.task.model.SO.SoDetail;
import com.deer.wms.ware.task.model.SO.SoMaster;
import com.deer.wms.ware.task.model.pickTask.*;
import com.deer.wms.ware.task.service.PickTaskService;
import com.deer.wms.ware.task.service.PushErpService;
import com.deer.wms.ware.task.service.SoDetailService;
import com.deer.wms.ware.task.service.impl.SoMasterServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

import static com.deer.wms.project.root.util.CollectionUtils.convertMap;

/**
 * @Author: xu
 * @Date: 2022/06/23/11:23
 * @Description:
 */
@Api(description = "直发虚仓，VMI特殊处理接口")
@RestController
@RequestMapping("/wave")
public class WaveController {
    @Autowired
    private WaveServiceImpl waveService;

    @Autowired
    private AsnMasterService asnMasterService;
    @Autowired
    private SoDetailService soDetailService;
    @Autowired
    private PickTaskService pickTaskService;
    @Autowired
    private SoMasterServiceImpl soMasterService;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private PackDetailService packDetailService;
    @Autowired
    private CellInfoService cellInfoService;

    @Autowired
    private AsnDetailService asnDetailService;

    @ApiOperation(value = "VMI触发")
    @PostMapping("inventoryVmi")
    public Result inventoryVmi(@RequestBody List<Inventory> list, @ApiIgnore @User CurrentUser currentUser) {
//        List<String> oldCellCodList = Arrays.asList(oldCellCods.split(","));
        waveService.inventoryVmi(list, currentUser);
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/manualCreatePickTask")
    @Transactional
    @ApiOperation(value = "产成品")
    public Result manualCreatePickTask(@RequestBody CreatePickTask createPickTask, @ApiIgnore @User CurrentUser currentUser) {

        List<PickTask> pickTaskList = new ArrayList<>();
        if (createPickTask.getBillNo().equals("") || createPickTask.getSoDetailId() == null || createPickTask.getCreatePickTaskDetails().size() <= 0) {
            return ResultGenerator.genFailResult(CommonCode.PARAMETER_ERROR);
        }
        List<PickTaskDto> list = pickTaskService.findList(new PickTaskCriteria(createPickTask.getSoDetailId(), 4));
        if (list.size() > 0) {
            return ResultGenerator.genFailResult(CommonCode.PICK_TASK_ALREADY_EXIST);
        }
        SoDetail soDetail = soDetailService.getById(createPickTask.getSoDetailId());
        SoMaster soMaster = soMasterService.findBy("bill_no", createPickTask.getBillNo());
        soMaster.setAssUserId(createPickTask.getUserId());
        soDetail.setPickUserId(createPickTask.getUserId());
//        UserInfo userinfo = userInfoService.getById(createPickTask.getUserId());
//        soDetail.setPickUserName(userinfo.getUserName());
//        soMaster.setAssUserName(userinfo.getUserName());
        //分配数量
        double allottedQuantity = 0;
        for (CreatePickTaskDetail createPickTaskDetail : createPickTask.getCreatePickTaskDetails()) {
            InventorySelectDto inventorySelectDto = inventoryService.findByInventoryId(new InventoryCriteria(createPickTaskDetail.getInventoryId())).get(0);
            //发运单的单位
            //拣货任务的单位
            PackDetail packDetailPick = packDetailService.getById(createPickTaskDetail.getPackDetailId());
            /**
             * 涉及到转换率
             */
//            double quantity = MyUtils.calculateDivide(soDetail.getPackDetailId(), inventorySelectDto.getPackDetailId(), createPickTaskDetail.getPickQuantity(), packDetail.getTransRatio());
            double quantity = createPickTaskDetail.getPickQuantity();
            inventorySelectDto.setAllotQuantity((inventorySelectDto.getAllotQuantity() == null ? 0.0 : inventorySelectDto.getAllotQuantity()) + quantity);
            inventoryService.updateById(inventorySelectDto);
            PickTask pickTask = new PickTask(
                    soDetail.getSoDetailId(),
                    soMaster.getSoMasterId(),
                    soMaster.getWareId(),
                    soMaster.getWareName(),
                    soMaster.getOrganizationId(),
                    soMaster.getOrganizationName(),
                    inventorySelectDto.getAreaCode(),
                    inventorySelectDto.getAreaName(),
                    inventorySelectDto.getShelfCode(),
                    inventorySelectDto.getShelfName(),
                    inventorySelectDto.getCellCode(),
                    inventorySelectDto.getCellName(),
                    inventorySelectDto.getItemCode(),
                    inventorySelectDto.getItemName(),
                    inventorySelectDto.getBatchId(),
                    inventorySelectDto.getBatchName(),
                    inventorySelectDto.getBoxCode(),
                    inventorySelectDto.getLpn(),
                    soDetail.getPackDetailId(),
                    soDetail.getPackDescribe(),
                    createPickTaskDetail.getPickQuantity(),
                    0,
                    inventorySelectDto.getInventoryId(),
                    1,
                    soDetail.getImgUrl()
            );
            pickTask.setPackDetailId(packDetailPick.getPackDetailId());
            pickTask.setPackDescribe(packDetailPick.getPackDescribe());
            pickTaskService.save(pickTask);
            pickTaskList.add(pickTask);
            allottedQuantity += createPickTaskDetail.getPickQuantity();
            Integer invenotryId = createPickTaskDetail.getInventoryId();
            Inventory inventory = inventoryService.getById(invenotryId);
            inventory.setAllotQuantity(createPickTaskDetail.getPickQuantity());
            //拣货分配
//            savePickTask(pickTask, currentUser);
        }

        soDetail.setAllottedQuantity(allottedQuantity + soDetail.getAllottedQuantity());
        soDetailService.updateById(soDetail);
        soMasterService.updateState(soMaster);

        if (ObjectUtil.isNull(currentUser)) {
            return ResultGenerator.genFailResult(CommonCode.MISSING_PERMISSION_PARAMTER);
        }
//        List<PickTask> pickTasks = pickTaskService.listByIds(Arrays.asList(pickIds.split(",")));
        for (PickTask pickTask : pickTaskList) {
            //特殊情况，拣货数量直接等于计划数量
            //这里也支持部分拣货的情况
            pickTask.setReviewQuantity(pickTask.getPickQuantity());
        }
        String cellCode = cellInfoService.findErpAreaId(createPickTask.getErpAreaId());
        String pickIds = pickTaskList.stream().map(item -> item.getPickTaskId().toString()).collect(Collectors.joining(","));

        soMasterService.allot(pickIds, cellCode);
        //扣减库存，生成出库单
        pickTaskService.pickAndSendOut(pickTaskList, currentUser, createPickTask.getErpAreaId());
        waveService.manualCreatePickTask(createPickTask, currentUser);
        return ResultGenerator.genSuccessResult();
    }

    /**
     * 先发配件
     *
     * @param createPickTask
     * @param currentUser
     * @return
     */
    @PostMapping("/commitStart")
    @Transactional
    public Result commitStart(@RequestBody CreatePickTask createPickTask, @ApiIgnore @User CurrentUser currentUser) {
        waveService.commitStart(createPickTask, currentUser);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "直发虚仓")
    @GetMapping("virtual")
    public Result virtual(Long ids, @ApiIgnore @User CurrentUser currentUser, Double vmiNumber) {
        waveService.virtual(ids, currentUser, vmiNumber);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "先发配件")
    @GetMapping("start")
    public Result start(Long ids, @ApiIgnore @User CurrentUser currentUser, Double vmiNumber) {
        waveService.start(ids, currentUser, vmiNumber);
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "WMS产品入库(数据回传ERP)", notes = "WMS产品入库(数据回传ERP)")
    @GetMapping("/toPutaway")
    public Result toPutaway(AsnMasterCriteria criteria, @ApiIgnore @User CurrentUser currentUser) {

        // 获取选中的入库任务
        // 解析前台
        List<Integer> idList = new ArrayList<>();
        String ids = criteria.getIds();
        if (ids != null && !ids.equals("")) {
            // 按照逗号分隔成多个任务单号
            String[] list = ids.split(",");
            for (String id : list) {
                idList.add(Integer.parseInt(id));
            }
        }
        List<AsnMaster> asnMasters = asnMasterService.listByIds(idList);
        List<Integer> billIds = new ArrayList<>();

        for (AsnMaster asnMaster : asnMasters) {
            Integer beforeNum = asnMaster.getBeforeNum();
            billIds.add(beforeNum);
        }
        Map<String, Object> map = new HashMap<>();
        map.put("billNo",asnMasters.listIterator().next().getBillNo());
        map.put("billTypeId", asnMasters.listIterator().next().getBillType());
        Map<String, AsnMaster> asnMasterMap = convertMap(asnMasters, AsnMaster::getBillNo);

        // 每一条明细对应一个库存事务
        List<String> billNos = asnMasters.stream().map(AsnMaster::getBillNo).collect(Collectors.toList());
        //同步拉取
        asnDetailService.savePurchaseOrder(map, asnMasterMap, billNos);
        for (AsnMaster asnMaster : asnMasters) {
            // 这里的qty只有用条明细才有意义
            waveService.accomplish(asnMaster, criteria.getCellCode(), currentUser, criteria.getQty(), criteria.getBatchName());
        }
        return ResultGenerator.genSuccessResult();
    }


    @ApiOperation(value = "WMS产品入库(数据回传ERP)", notes = "WMS产品入库(数据回传ERP)")
    @GetMapping("/toPutawayErp")
    public Result toPutawayErp(AsnMasterCriteria criteria, @ApiIgnore @User CurrentUser currentUser) {
        // 获取选中的入库任务
        // 解析前台
        List<Integer> idList = new ArrayList<>();
        String ids = criteria.getIds();
        if (ids != null && !ids.equals("")) {
            // 按照逗号分隔成多个任务单号
            String[] list = ids.split(",");
            for (String id : list) {
                idList.add(Integer.parseInt(id));
            }
        }
        List<AsnMaster> asnMasters = asnMasterService.listByIds(idList);
        // 每一条明细对应一个库存事务
        for (AsnMaster asnMaster : asnMasters) {
            // 这里的qty只有用条明细才有意义
            waveService.accomplishErp(asnMaster, criteria.getCellCode(), currentUser);
        }
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("/toPutawayErpDetail")
    @ApiOperation(value = "WMS产品入库(数据回传ERP)", notes = "WMS产品入库(数据回传ERP)")
    public Result toPutawayErpDetail(AsnMasterCriteria criteria, @ApiIgnore @User CurrentUser currentUser) {
        List<String> detailIds = Arrays.asList(StringUtils.split(criteria.getIds()));
        waveService.accomplishErp(detailIds, criteria.getCellCode(), currentUser);
        return ResultGenerator.genSuccessResult();
    }


    @GetMapping("bathServer")
    public void bathServer() {
        waveService.bathServer();
    }

    @ApiOperation(value = "出库详情直发虚仓")
    @GetMapping("/virtualSoDetail")
    public Result virtualSoDetail(String ids, @ApiIgnore @User CurrentUser currentUser) {
        List<SoDetail> soDetails = soDetailService.listByIds(Arrays.asList(ids.split(",")));
        for (SoDetail soDetail : soDetails) {
            waveService.virtualSoDetail(soDetail, currentUser);
        }
        return ResultGenerator.genSuccessResult();
    }

    @Autowired
    private AreaInfoService areaInfoService;
    @Autowired
    private PushErpService pushErpService;

    @Autowired
    private ItemInfoService itemInfoService;
    @GetMapping("/SumList")
    public Result SumList(InventoryCriteria criteria) {
        AreaInfo areaInfo = areaInfoService.getOne(new QueryWrapper<AreaInfo>().eq("erp_area_id", criteria.getErpAreaId()).last("limit 1"));
        List<InventorySumListDto> inventories = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(areaInfo.getWaveType())&&areaInfo.getWaveType() == 2) {
            Map<String, Object> map = new HashMap<>();
            map.put("stockId", areaInfo.getErpAreaId());
            List<InventoryVo> inventory = pushErpService.inventory(map);
            List<String> itemCodes = inventory.stream().map(item -> item.getItemNumber()).collect(Collectors.toList());
            List<ItemInfo> infos = itemInfoService.list(new QueryWrapper<ItemInfo>().in("item_code", itemCodes));
            Map<String, ItemInfo> itemMap = convertMap(infos, ItemInfo::getItemCode);

            for (InventoryVo inventoryVo : inventory) {
                InventorySumListDto erpInv = new InventorySumListDto();
                erpInv.setItemCode(inventoryVo.getItemNumber());
                erpInv.setErpItemId(inventoryVo.getItemId());
                if (ObjectUtil.isNotEmpty(itemMap.get(inventoryVo.getItemNumber()))) {
                    erpInv.setItemName(itemMap.get(inventoryVo.getItemNumber()).getItemName());
                }

                erpInv.setBatchName(inventoryVo.getBatchNo());
                erpInv.setOne(inventoryVo.getQty());
                erpInv.setThree(0.00);
                erpInv.setThree(0.00);
                inventories.add(erpInv);
            }
            PageInfo pageInfo = new PageInfo(inventories);
            return ResultGenerator.genSuccessResult(pageInfo);
        } else {
            PageHelper.startPage(criteria.getPageNum(), criteria.getPageSize());
            List<Inventory> list = inventoryService.findSame(criteria);
            PageInfo pageInfo = new PageInfo(list);
            return ResultGenerator.genSuccessResult(pageInfo);
        }
    }
}
